﻿/**************************************************************
 * St. Sana - A file/folder scanner originall designed for    *
 * Open Media Library (open-media-library.googlecode.com)     *
 *                                                            *
 * Available for use by ANY project that wants to use it.     *
 * St. Sana is covered by the Apache 2 license.               *
 * Feel free to use this software however you like so as long *
 * as you follow the guidelines of above mentioned license.   *
 * Written by David J. Shultz (djshultz@gmail.com)            *
 **************************************************************/

using System;
using System.IO;
using NUnit.Framework;

using StSana;

namespace StSanaTestSuite
{
    [TestFixture]
    public class TServant
    {
        static string BASE_TV_TEST_PATH = @"..\..\..\Test Scenarios\TV Tests";
        static string BASE_MOVIES_TEST_PATH = @"..\..\..\Test Scenarios\Movie Tests";

        [Test]
        [Category("Main")]
        public void TEST_BUILD_SSFOLDER_DOM_WORKS()
        {
            Servant s = new Servant();
            s.AddBasePath(BASE_TV_TEST_PATH);
            s.Scan();

            //Assert.AreEqual(2, s.Entities.Count);
        }

        [Test]
        [Category("Main")]
        public void TEST_SERVANT_MAINTAINS_A_LIST_OF_PATHS_TO_SCAN()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, @"Single Folder With Multiple Files From a Single Show"));

            Assert.AreEqual(1, s.BasePaths.Count);
            Assert.AreEqual(Path.Combine(BASE_TV_TEST_PATH, @"Single Folder With Multiple Files From a Single Show"),
                            s.BasePaths[0]);
        }

        #region TV Show tests

        [Test]
        [Category("TV")]
        public void TEST_TV_TESTS__SINGLE_FILE_CONTAINING_MORE_THEN_ONE_EPISODE()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, @"Single File Containing More then One Episode"));
            s.Scan();

            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual(1, s.Entities[0].Series.Count);
            //Assert.AreEqual(4, s.Entities[0].Series[0].Videos.Count); how do we get this to recognize that these are multi-episode files?
            // and do we care?
        }

        [Test]
        [Category("TV")]
        public void TEST_TV_TESTS__SCAN_SINGLE_FOLDER_WITH_MULTIPLE_FILES_FOR_A_SINGLE_SHOW()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, @"Single Folder With Multiple Files From a Single Show"));
            s.Scan();
            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual(1, s.Entities[0].Series.Count);
            Assert.AreEqual(3, s.Entities[0].Series[0].Videos.Count);
            Assert.AreEqual(@"Pilot (1)S01E01.avi", s.Entities[0].Series[0].Videos[0].Name);
            Assert.AreEqual(1, s.Entities[0].Series[0].Number);
            Assert.AreEqual(1, s.Entities[0].Series[0].Videos[0].EpisodeNumbers[0]);

            Assert.AreEqual(@"Pilot (2)S01E02.avi", s.Entities[0].Series[0].Videos[1].Name);
            Assert.AreEqual(1, s.Entities[0].Series[0].Number);
            Assert.AreEqual(2, s.Entities[0].Series[0].Videos[1].EpisodeNumbers[0]);
            
            Assert.AreEqual(@"Tabula RasaS01E03.avi", s.Entities[0].Series[0].Videos[2].Name);
            Assert.AreEqual(1, s.Entities[0].Series[0].Number);
            Assert.AreEqual(3, s.Entities[0].Series[0].Videos[2].EpisodeNumbers[0]);
        }

        [Test]
        [Category("TV")]
        public void TEST_TV_TESTS__SINGLE_FOLDER_WITH_MULTIPLE_FILES_FROM_MULTIPLE_SHOWS()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, @"Single Folder With Multiple Files From Multiple Shows"));
            s.Scan();

            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual(3, s.Entities[0].Series.Count);
        }

        [Test]
        [Category("TV")]
        public void TEST_TV_TESTS__SINGLE_FOLDER_WITH_SUBFOLDERS_FOR_SEASONS()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, "Single Folder With SubFolders For Seasons"));
            s.Scan();

            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual(4, s.Entities[0].Series.Count);

            Series s1 = s.Entities[0].Series[0];
            Assert.AreEqual("Lost", s.Entities[0].Name);
            Assert.AreEqual(4, s1.Number);
            Assert.AreEqual(1, s1.Videos.Count);
            Assert.AreEqual("04E01 - a new hope.avi", s1.Videos[0].Name);
            Assert.AreEqual(1, s1.Videos[0].EpisodeNumbers.Count);
            Assert.AreEqual(1, s1.Videos[0].EpisodeNumbers[0]);

            Series s2 = s.Entities[0].Series[1];
            Assert.AreEqual(1, s2.Number);
            Assert.AreEqual(1, s2.Videos.Count);
            Assert.AreEqual("1x01.avi", s2.Videos[0].Name);
            Assert.AreEqual(1, s2.Videos[0].EpisodeNumbers.Count);
            Assert.AreEqual(1, s2.Videos[0].EpisodeNumbers[0]);

            Series s3 = s.Entities[0].Series[2];
            Assert.AreEqual(3, s3.Number);
            Assert.AreEqual(1, s3.Videos.Count);
            Assert.AreEqual("Lost - S3x01.avi", s3.Videos[0].Name);
            Assert.AreEqual(1, s3.Videos[0].EpisodeNumbers.Count);
            Assert.AreEqual(1, s3.Videos[0].EpisodeNumbers[0]);

            Series s4 = s.Entities[0].Series[3];
            Assert.AreEqual(2, s4.Number);
            Assert.AreEqual(1, s4.Videos.Count);
            Assert.AreEqual("Lost2x02.avi", s4.Videos[0].Name);
            Assert.AreEqual(1, s4.Videos[0].EpisodeNumbers.Count);
            Assert.AreEqual(2, s4.Videos[0].EpisodeNumbers[0]);
        }

        [Category("TV")]
        public void TEST_TV_TESTS__SINGLE_FOLDER_WITH_SUBFOLDERS_FOR_SEASONS_AND_EPISODES()
        {
        }

        [Test]
        [Category("TV")]
        public void TEST_TV_TESTS__SINGLE_FOLDER_WITH_SUBFOLDERS_FOR_SEASONS_AND_EPISODES_WITH_SPECIAL_EPISODES_IN_SEASON_FOLDER()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, @"Single Folder With SubFolders For Seasons And Episodes with Special Episodes in Season Folder"));
            s.Scan();

            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual("Lost", s.Entities[0].Name);

            Assert.AreEqual(1, s.Entities[0].Series.Count);
            Assert.AreEqual(1, s.Entities[0].Series[0].Number);
            Series s1 = s.Entities[0].Series[0];

            Assert.AreEqual(2, s1.Videos.Count);
            Assert.AreEqual(1, s1.Videos[0].EpisodeNumbers.Count);
            Assert.AreEqual(1, s1.Videos[0].EpisodeNumbers[0]);

            Assert.AreEqual(1, s1.Videos[1].EpisodeNumbers.Count);
            Assert.AreEqual(0, s1.Videos[1].EpisodeNumbers[0]);
            Assert.IsTrue(s1.Videos[1].IsNonStandardVideo);
        }

        [Test]
        [Category("TV")]
        public void TEST_TV_TESTS__SINGLE_FOLDER_WITH_SUBFOLDERS_FOR_SEASONS_AND_EPISODES_WITH_SPECIAL_EPISODES_IN_SHOW_FOLDER()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_TV_TEST_PATH, @"Single Folder With SubFolders For Seasons And Episodes with Special Episodes in Show Folder"));
            s.Scan();

            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual(1, s.Entities[0].Series.Count);
            Assert.AreEqual(2, s.Entities[0].Series[0].Videos.Count);
        }

        #endregion

        #region Movie Tests
        [Test]
        [Category("Movies")]
        public void TEST_MOVIES_TESTS__SCAN_MAIN_FOLDER_WITH_MULTIPLE_MOVIE_SUBFOLDERS()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_MOVIES_TEST_PATH, "Main Folder with Multiple Movie SubFolders"));
            s.Scan();
            Assert.AreEqual(3, s.Entities.Count);

            Entity e1 = s.Entities[0];
            Assert.AreEqual(1, e1.Series.Count);
            Series s1 = e1.Series[0];
            Assert.AreEqual("The Great Escape", s1.Name);
            Assert.AreEqual(1, s1.Videos.Count);
            Assert.AreEqual("The Great Escape", s1.Videos[0].Name);

            Entity e2 = s.Entities[1];
            Assert.AreEqual(1, e2.Series.Count);
            Series s2 = e2.Series[0];
            Assert.AreEqual("Alien", s2.Name);
            Assert.AreEqual(1, s2.Videos.Count);
            Assert.AreEqual(2, s2.Videos[0].FileCount);
            Assert.IsTrue(s2.Videos[0].Files[0].ToUpperInvariant().Contains("move cd2.avi".ToUpperInvariant()));
            Assert.IsTrue(s2.Videos[0].Files[1].ToUpperInvariant().Contains("movie cd1.avi".ToUpperInvariant()));

            Entity e3 = s.Entities[2];
            Assert.AreEqual(1, e3.Series.Count);
            Series s3 = e3.Series[0];
            Assert.AreEqual("Aliens", s3.Name);
            Assert.AreEqual(1, s3.Videos.Count);
            Assert.AreEqual("Aliens", s3.Videos[0].Name);
            Assert.IsTrue(s3.Videos[0].Files[0].ToUpperInvariant().Contains("aliens.m2ts".ToUpperInvariant()));
        }

        [Test]
        [Category("Movies")]
        public void TEST_MOVIES_TESTS__Genre_SubFolders_with_Multiple_Movies_Files()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_MOVIES_TEST_PATH, "Genre SubFolders with Multiple Movies Files"));
            s.Scan();

            Assert.AreEqual(3, s.Entities.Count);

            Entity drama = s.Entities[0];
            Entity kids = s.Entities[1];
            Entity sciFi = s.Entities[2];

            Assert.AreEqual("Drama", drama.Name);
            Assert.AreEqual("Kids", kids.Name);
            Assert.AreEqual("SciFi", sciFi.Name);

            Assert.AreEqual(1, drama.Series.Count);
            Assert.AreEqual(1, drama.Series[0].Videos.Count);
            Assert.AreEqual("Drama", drama.Series[0].Videos[0].Name);
            Assert.IsTrue(drama.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("movie1.avi".ToUpperInvariant()));

            Assert.AreEqual(1, kids.Series.Count);
            Assert.AreEqual(1, kids.Series[0].Videos.Count);
            Assert.AreEqual("Kids", kids.Series[0].Videos[0].Name);
            Assert.IsTrue(kids.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("movie1.avi".ToUpperInvariant()));

            Assert.AreEqual(1, sciFi.Series.Count);
            Assert.AreEqual(1, sciFi.Series[0].Videos.Count);
            Assert.AreEqual(2, sciFi.Series[0].Videos[0].FileCount);
            Assert.AreEqual("SciFi", sciFi.Series[0].Videos[0].Name);
            Assert.IsTrue(sciFi.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("movie1.avi".ToUpperInvariant()));
        }

        [Test]
        [Category("Movies")]
        public void TEST_MOVIES_TESTS__Genre_SubFolders_With_Multiple_Movie_Files_video_ts_or_other_types_of_subfolders()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_MOVIES_TEST_PATH, "Genre SubFolders With Multiple Movie Files (video_ts or other types of subfolders)"));
            s.Scan();

            Assert.AreEqual(3, s.Entities.Count);

            Entity drama = s.Entities[0];
            Entity kids = s.Entities[1];
            Entity scifi = s.Entities[2];

            Assert.AreEqual(Serf.EntityType.MOVIE, drama.EntityType);
            Assert.AreEqual(Serf.EntityType.COLLECTION, kids.EntityType);
            Assert.AreEqual(Serf.EntityType.COLLECTION, kids.EntityType);

            Assert.AreEqual(1, drama.Series.Count);
            Assert.AreEqual(1, drama.Series[0].Videos.Count);
            Assert.AreEqual(1, drama.Series[0].Videos[0].FileCount);
            Assert.AreEqual("Drama", drama.Series[0].Videos[0].Name);

            Assert.AreEqual(1, kids.Series.Count);
            Assert.AreEqual(1, kids.Series[0].Videos.Count);
            Assert.AreEqual("Movie 1", kids.Series[0].Videos[0].Name);
            Assert.AreEqual(1, kids.Series[0].Videos[0].FileCount);
            Assert.IsTrue(kids.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("movie1.mkv".ToUpperInvariant()));

            Assert.AreEqual(2, scifi.Series.Count);
            Assert.AreEqual("Movie 1", scifi.Series[0].Name);
            Assert.AreEqual(1, scifi.Series[0].Videos.Count);
            Assert.AreEqual(1, scifi.Series[0].Videos[0].FileCount);
            Assert.IsTrue(scifi.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("movie1.ogm".ToUpperInvariant()));

            Assert.AreEqual("Movie2", scifi.Series[1].Name);
            Assert.AreEqual(1, scifi.Series[1].Videos.Count);
            Assert.AreEqual(1, scifi.Series[1].Videos[0].FileCount);
            Assert.IsTrue(scifi.Series[1].Videos[0].Files[0].ToUpperInvariant().Contains("movie2.avi".ToUpperInvariant()));
        }

        [Test]
        [Category("Movies")]
        public void TEST_MOVIES_TEST__Single_Folder_With_Multiple_Movie_Files()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_MOVIES_TEST_PATH, "Single Folder With Multiple Movie Files"));
            s.Scan();

            Assert.AreEqual(3, s.Entities.Count);
            Entity e1 = s.Entities[0];
            Assert.AreEqual(1, e1.Series.Count);
            Assert.AreEqual("Alien Resurrection", e1.Name);
            Assert.AreEqual(1, e1.Series[0].Videos.Count);
            Assert.AreEqual("Alien Resurrection", e1.Series[0].Name);
            Assert.AreEqual(1, e1.Series[0].Videos[0].FileCount);
            Assert.AreEqual("Alien Resurrection", e1.Series[0].Videos[0].Name);
            Assert.IsTrue(e1.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("Alien Resurrection.avi".ToUpperInvariant()));

            Entity e2 = s.Entities[1];
            Assert.AreEqual(1, e2.Series.Count);
            Assert.AreEqual("Alien", e2.Name);
            Assert.AreEqual(1, e2.Series[0].Videos.Count);
            Assert.AreEqual("Alien", e2.Series[0].Name);
            Assert.AreEqual(1, e2.Series[0].Videos[0].FileCount);
            Assert.AreEqual("Alien", e2.Series[0].Videos[0].Name);
            Assert.IsTrue(e2.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("Alien.avi".ToUpperInvariant()));

            Entity e3 = s.Entities[2];
            Assert.AreEqual(1, e3.Series.Count);
            Assert.AreEqual("Aliens", e3.Name);
            Assert.AreEqual(1, e3.Series[0].Videos.Count);
            Assert.AreEqual("Aliens", e3.Series[0].Name);
            Assert.AreEqual(1, e3.Series[0].Videos[0].FileCount);
            Assert.AreEqual("Aliens", e3.Series[0].Videos[0].Name);
            Assert.IsTrue(e3.Series[0].Videos[0].Files[0].ToUpperInvariant().Contains("Aliens.avi".ToUpperInvariant()));
        }

        [Test]
        [Category("Movies")]
        public void TEST_MOVIES_TEST__Single_Folder_With_Multiple_Movie_Files__video_ts_or_other_types_of_subfolders()
        {
            Servant s = new Servant();
            s.AddBasePath(Path.Combine(BASE_MOVIES_TEST_PATH, "Single Folder With Multiple Movie Files (video_ts or other types of subfolders)"));
            s.Scan();

            Assert.AreEqual(1, s.Entities.Count);
            Assert.AreEqual("Single Folder With Multiple Movie Files (video_ts or other types of subfolders)", s.Entities[0].Name);
        }
        #endregion
    }
}
